/*
 * Block comments with details of changes
 */

global class ReadAndPopulateBatch implements Database.batchable<String>{
 
    private String textData;
    private SObjectType obj ;
    private List<String> keys;
    private String separator;
    private String err;
    ///处理数据: 根据数据的类型返回指定数据类型的数据
    private Object dataHandler(object o, String type){
    	if(type == 'CURRENCY' || type == 'DOUBLE' ||type == 'PERCENT'){
        //小数
            return Decimal.valueOf((String) o);
        }else if(type == 'INTEGER' ){
        //整数
           return Integer.valueOf((String) o);
        }else if(type == 'DATE'){
        //日期
           return Date.valueOf((String) o);
        }else if(type == 'DATETIME'){
        //日期时间
           return DateTime.valueOf((String) o);
        }else if(type == 'TIME'){
        //时间
           String t = (String) o;
           if(t.length() == 0) return null;
           List<String>ts = t.split(':',-1);
           if(ts.size() == 1) return Time.newInstance(Integer.valueOf(ts[0]),0,0,0);
           return ts.size() > 2 ? Time.newInstance(Integer.valueOf(ts[0]),Integer.valueOf(ts[1]),Integer.valueOf(ts[2]),0):Time.newInstance(Integer.valueOf(ts[0]),Integer.valueOf(ts[1]),0,0);
        }else {
        //字符串
        	return o;
        }
        
    }
    global ReadAndPopulateBatch(String textData,SObjectType obj ,List<String> keys,String separator)
    {       
        this.textData = textData;
        this.obj = obj;
        this.keys = keys;
        this.separator = separator == null ? ',': separator;
    }
  
   global Iterable<String> start(Database.batchableContext info){
       //判断换行符 默认为\n 
       String line_s = '\n';
       if(this.textData.contains('\r\n')) {
       		line_s = '\r\n';
       }else{
       		if(this.textData.contains('\r'))line_s = '\r';
       }
       
       return new LineReader(this.textData,line_s);
   }
   global void execute(Database.batchableContext info, List<String> scope){
       List<SObject> ss = new List<SObject>();
       //按顺序匹配字段
       for(String str :scope){
       		SObject s = this.obj.newSobject();
           ///获取字段的类型
           Map<String,String>dtype = new Map<String,String>();
           for(Integer i = 0;i< keys.size() ; i++){
           		dtype.put(keys[i],this.obj.getDescribe().fields.getMap().get(keys[i]).getDescribe().getType()+'');
           }
           ///解析每行数据
          	List<String> vals = str.split(this.separator,-1);
            for(Integer i = 0;i< vals.size() ; i++){
                //赋值到对象里
            	s.put(this.keys[i],this.dataHandler(vals[i],dtype.get(keys[i])));
            }
            try{
              upsert s;  
       		}catch(Exception e){
                this.err += str +':'+e.getMessage() +'\n';
       		}
           //保存到数组
           ss.add(s);
           	
       }          
       upsert ss;
/*
        SavePoint sp = Database.setSavePoint();
       try{
       }catch(Exception e){
       		Database.rollback(sp);
       }*/

   }
   global void finish(Database.batchableContext info){
   } 
}